package thread.lock;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * @program: Multhread
 * @description: 这个是AQS锁的子类
 * @author: zhanghz001
 * @create: 2021-03-05 09:01
 **/
public class MyAbstractQueuedSynchronizer extends AbstractQueuedSynchronizer {
    public MyAbstractQueuedSynchronizer(int count) {
        super();
        setState(count);
    }
    
    @Override
    protected boolean tryRelease(int arg) {
        setState(super.getState() + arg);
        return true;
    }
    
    @Override
    protected boolean tryAcquire(int arg) {
        setState(super.getState() - arg);
        return getState() > 0;
    }
    
    @Override
    protected boolean tryReleaseShared(int arg) {
        //cas 自旋
        for (; ; ) {
            int current = getState();
            int newCount = current + arg;
            if (compareAndSetState(current, newCount)) {
                return true;
            }
        }
    }
    
    @Override
    protected int tryAcquireShared(int arg) {
        //自旋,不断获取,需要通过原子性的操作才可以
        for (; ; ) {
            int current = getState();
            int newCount = current - arg;
            if (newCount < 0 || compareAndSetState(current, newCount)) {
                return newCount;
            }
        }
        
    }
    
    public static void main(String[] args) {
        int count = 1;
        MyAbstractQueuedSynchronizer lock = new MyAbstractQueuedSynchronizer(count);
        for (int i = 0; i < 10; i++) {
            final int b = i;
            new Thread(() -> {
                lock.acquireShared(1);
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    System.out.println(b);
                    lock.releaseShared(1);
                }
            }).start();
        }
    }
}
